
/*
 * Copyright (C) 2015-2019 Alibaba Group Holding Limited
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "aos/kernel.h"
#include "aos/list.h"
#include "aos/compiler.h"
#include "aos/hal/gpio.h"
#include "aos/hal/uart.h"

#include "ulog/ulog.h"
#include "wlt3048nz.h"


static uart_dev_t st_zigbee_uart;
static gpio_dev_t st_zigbee_poweron;

#define WLT_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
#define WLT_NTOHS(x) WLT_HTONS(x)


#define MODULE_NAME                    "WTL_ZIGBEE"

#pragma pack (1)
typedef struct st_local_info{
    uint8_t magic_head;
    uint8_t command;
    uint16_t local_addr;
    uint16_t protocol_type;
    uint8_t  status;
    uint16_t version;
    uint8_t  magic_tail;
}st_local_info_t;

typedef struct st_localdevinfo {
    uint8_t devname[16];
    uint8_t devpwd[16];
    uint8_t workmode;
    uint8_t channel;
    uint16_t panid;
    uint16_t local_addr;
    uint16_t dest_addr;
    uint8_t datarate;
    uint8_t powerlevel;
    uint8_t retrynum;
    uint16_t retry_timeout;
    uint8_t serial_rate;
    uint8_t serial_data_bit;
    uint8_t serial_stop_bit;
    uint8_t serial_parity;
    uint8_t serial_timeout;
    uint8_t serial_byteout;
    uint8_t sendmode;
}st_dev_info_t;

typedef struct st_devinfosetrsp {
    uint8_t magic_head;
    uint8_t command;
    uint16_t addr;
    uint8_t response;
    uint8_t magic_tail;
}st_dev_info_rsp_t;

typedef struct st_devsearchrsp {
    uint8_t magic_head;
    uint8_t command;
    uint16_t addr;
    uint16_t protocol_type;
    uint8_t status;
    uint8_t magic_tail;
}st_dev_search_rsp_t;

typedef struct st_hostdatarsp {
    uint8_t magic_head;
    uint8_t command;
    uint8_t status;
    uint8_t magic_tail;
}st_host_data_rsp_t;
#pragma pack ()

static aos_mutex_t st_zigbee_uart_mutex = {0};
static int32_t     zigbee_init_flag = 0; 
static uint16_t    g_uslocal_addr = -1;
static st_dev_info_t g_stlocal_devinfo = {0};

void dump_zigbee_deviceinfo(void)
{
    printf("\r\n=====================\r\n");
    printf("devname : %s ==\r\n", g_stlocal_devinfo.devname);
    printf("passwd : %s ==\r\n", g_stlocal_devinfo.devpwd);
    printf("workmode : %d ==\r\n", g_stlocal_devinfo.workmode);
    printf("channel : %d ==\r\n", g_stlocal_devinfo.channel);
    printf("panid : 0x%x ==\r\n", g_stlocal_devinfo.panid);
    printf("local_addr : 0x%x ==\r\n", g_stlocal_devinfo.local_addr);
    printf("dest_addr : 0x%x ==\r\n", g_stlocal_devinfo.dest_addr);
    printf("datarate : %d ==\r\n", g_stlocal_devinfo.datarate);
    printf("powerlevel : %d ==\r\n", g_stlocal_devinfo.powerlevel);
    printf("retrynum : %d ==\r\n", g_stlocal_devinfo.retrynum);
    printf("retry_timeout : %d ==\r\n", g_stlocal_devinfo.retry_timeout);
    printf("serial_rate : %d ==\r\n", g_stlocal_devinfo.serial_rate);
    printf("serial_data_bit : %d ==\r\n", g_stlocal_devinfo.serial_data_bit);
    printf("serial_stop_bit : %d ==\r\n", g_stlocal_devinfo.serial_stop_bit);
    printf("serial_parity : %d ==\r\n", g_stlocal_devinfo.serial_parity);
    printf("serial_timeout : %d ==\r\n", g_stlocal_devinfo.serial_timeout);
    printf("serial_byteout : %d ==\r\n", g_stlocal_devinfo.serial_byteout);
    printf("sendmode : %d ==\r\n", g_stlocal_devinfo.sendmode);
}

int32_t wlt3408nz_get_local_addr(uint16_t *pus_localaddr)
{
    int32_t ret = 0;
    uint32_t recv_size = 0;
    uint8_t send_cmd[3] = {0xAB, 0xD1, 0xBA};
    st_local_info_t st_localinfo = {0};

    if (NULL == pus_localaddr) {
        LOGE(MODULE_NAME,"Invalid input, fail to get local id \r\n");
        return -1;
    }
    
    if (zigbee_init_flag == 0) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet, fail to get local id \r\n");
        return -1;
    }

    if (g_uslocal_addr != 0xFFFF) {
        *pus_localaddr = g_uslocal_addr;
        return 0;
    }
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);
    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to get devid for uart send fail %d \r\n", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_localinfo, sizeof(st_localinfo), 
                            &recv_size, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (ret || recv_size != sizeof(st_localinfo)) {
        LOGE(MODULE_NAME,"Fail to get devid for uart recv fail %d, recv %d \r\n", ret, recv_size);
        return -1;
    }
    
    if (st_localinfo.magic_head != 0xAB
        || st_localinfo.magic_tail != 0xBA
        || st_localinfo.command != 0xD1
        || WLT_NTOHS(st_localinfo.protocol_type) != 0x10) {
        LOGE(MODULE_NAME,"Invalid response at get devid \r\n");
        return -1;
    }
        
    g_uslocal_addr = WLT_NTOHS(st_localinfo.local_addr);
    *pus_localaddr = WLT_NTOHS(st_localinfo.local_addr);
    return 0;
}

static int32_t wlt3408nz_dev_reset()
{
    int32_t ret = 0;

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }
    
    ret = hal_gpio_output_low(&st_zigbee_poweron);
    if (ret) {
        LOGE(MODULE_NAME, "GPIO st_zigbee_en output low fail %d \r\n", ret);
        return -1;
    }
    
    aos_msleep(10);
    
    ret = hal_gpio_output_high(&st_zigbee_poweron);
    if (ret) {
        LOGE(MODULE_NAME, "GPIO st_zigbee_en output high fail %d \r\n", ret);
        return -1;
    }

    return 0;
}

static int32_t wlt3408nz_dev_reset_cmd(uint16_t addr)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD7, 0x00, 0x00, 0x00, 0x10, 0xBA};
    uint8_t resp[4] = {0};

    send_cmd[2] = WLT_HTONS(addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(addr) >> 8) & 0xFF;
    
    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to reset device for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, resp, sizeof(resp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (ret == 0) {
        /*recv reset response , it means reset fail*/
        LOGE(MODULE_NAME, "reset resp 0x%x, 0x%x, 0x%x, 0x%x", resp[0],
                resp[1], resp[2], resp[3]);
        return -1;
    }
    
    return 0;
}

static int32_t wlt3408nz_get_devinfo(uint16_t local_addr, st_dev_info_t *pstdevinfo)
{
    int32_t ret = 0;
    uint32_t expect_len = 0;
    uint32_t recved_len = 0;
    uint8_t  *puc_recv_info = NULL;
    uint8_t send_cmd[] = {0xAB, 0xD2, 0x00, 0x00, 0x00, 0x00, 0xBA};
    
    if (NULL == pstdevinfo) {
        LOGE(MODULE_NAME,"Inalid input");
        return -1;
    }

    send_cmd[2] = WLT_HTONS(local_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(local_addr) >> 8) & 0xFF;
    send_cmd[5] = sizeof(st_dev_info_t);
    expect_len = 12 + sizeof(st_dev_info_t);

    puc_recv_info = aos_malloc(expect_len);
    if (NULL == puc_recv_info) {
        LOGE(MODULE_NAME,"buffer %d malloc fail", expect_len);
        return -1;
    }
    
    memset(puc_recv_info, 0, expect_len);
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to get devinfo for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        aos_free(puc_recv_info);
        return -1;
    }

    /*recv the first 4 bytes for fail response length is 4 bytes*/
    ret = hal_uart_recv_II(&st_zigbee_uart, puc_recv_info, 4, 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (recved_len != 4) {
        LOGE(MODULE_NAME,"Fail to get devinfo for uart recv fail %d, recv %d \r\n", ret, recved_len);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        aos_free(puc_recv_info);
        return -1;
    }

    if (puc_recv_info[0] != 0xAB) {
        LOGE(MODULE_NAME, "cmd excute fail , the first 4 byte is %d, %d, %d, %d", 
            puc_recv_info[0], puc_recv_info[1], puc_recv_info[2], puc_recv_info[3]);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        aos_free(puc_recv_info);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, puc_recv_info + 4, expect_len - 4, 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (ret || recved_len != expect_len - 4) {
        LOGE(MODULE_NAME,"Fail to get devinfo for uart recv fail %d, recv %d \r\n", ret, recved_len);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        aos_free(puc_recv_info);
        return -1;
    }

    memcpy(pstdevinfo, puc_recv_info + 6, sizeof(st_dev_info_t));
    pstdevinfo->panid = WLT_NTOHS(pstdevinfo->panid);
    pstdevinfo->local_addr = WLT_NTOHS(pstdevinfo->local_addr);
    pstdevinfo->dest_addr = WLT_NTOHS(pstdevinfo->dest_addr);
    pstdevinfo->retry_timeout = WLT_NTOHS(pstdevinfo->retry_timeout);
    
    return ret;
}

int32_t wlt3408nz_dev_init(gpio_dev_t *pst_poweron_pin, uart_dev_t *pst_comm_uart)
{
    int32_t ret = 0;

    
    if (NULL == pst_poweron_pin || NULL == pst_comm_uart) {
        printf("wlt3408nz_dev_init fail ,invalid input \r\n");
        return -1;
    }

    if (zigbee_init_flag) {
        printf("wlt3408nz_dev_init fail , already inited \r\n");
        return -1;
    }
    
    ret = hal_gpio_init(pst_poweron_pin);
    if (ret) {
        printf("GPIO st_zigbee_en init fail %d \r\n", ret);
        return -1;
    }

    ret = hal_gpio_output_low(pst_poweron_pin);
    if (ret) {
        printf("GPIO st_zigbee_en output low fail %d \r\n", ret);
        return -1;
    }

    
    /*init uart */
    ret = hal_uart_init(pst_comm_uart);
    if (ret) {
        printf("zigbee uart init fail , port %d \r\n", st_zigbee_uart.port);
        return -1;
    }
    memcpy(&st_zigbee_uart, pst_comm_uart, sizeof(st_zigbee_uart));
    memcpy(&st_zigbee_poweron, pst_poweron_pin, sizeof(st_zigbee_poweron));
    ret = aos_mutex_new(&st_zigbee_uart_mutex);
    if (ret) {
        printf("uart mutex new fail\r\n");
        return -1;
    }
    
    zigbee_init_flag = 1;
    
    ret = wlt3408nz_get_local_addr(&g_uslocal_addr);
    if (ret) {
        printf("fail to get local addr \r\n");
        return -1;
    }

    ret = wlt3408nz_get_devinfo(g_uslocal_addr, &g_stlocal_devinfo);
    if (ret) {
        printf("fail to get local devinfo \r\n");
        return -1;
    }
    
    return 0;
}

int32_t wlt3408nz_get_dev_work_mode(uint8_t *pucworkmode)
{
    if (NULL == pucworkmode) {
        LOGE(MODULE_NAME, "Invalid input");
        return -1;
    }

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    *pucworkmode = g_stlocal_devinfo.workmode;
    
    return 0;
}

int32_t wlt3408nz_set_dev_work_mode(uint8_t workmode)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};
    
    if (workmode >= WORKMODE_MAX) {
        LOGE(MODULE_NAME, "Invalid input %d", workmode);
        return -1;
    }

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }
    
    if (workmode == g_stlocal_devinfo.workmode) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, workmode);
    send_cmd[5] = sizeof(workmode);
    send_cmd[6] = workmode;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set workmode for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME, "Fail to set workmode for uart recv fail %d, recv %d", ret, recved_len);
        return -1;
    }
    
    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", g_uslocal_addr);
            return ret;
        }
        g_stlocal_devinfo.workmode = workmode;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_set_local_addr(uint16_t local_addr)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }
    
    if (local_addr == g_stlocal_devinfo.local_addr) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, local_addr);
    send_cmd[5] = sizeof(local_addr);
    send_cmd[6] = WLT_HTONS(local_addr) & 0xFF;
    send_cmd[7] = (WLT_HTONS(local_addr) >> 8) & 0xFF;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set localaddr for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME,"Fail to get localaddr for uart recv fail %d, recv %d \r\n", ret, recved_len);
        return -1;
    }
    
    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", local_addr);
            return ret;
        }
        g_stlocal_devinfo.local_addr = local_addr;
        g_uslocal_addr = local_addr;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_get_dest_addr(uint16_t *pusdest_addr)
{
    if (NULL == pusdest_addr) {
        LOGE(MODULE_NAME, "Invalid input");
        return -1;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    *pusdest_addr = g_stlocal_devinfo.dest_addr;

    return 0;
}

int32_t wlt3408nz_set_dest_addr(uint16_t dest_addr)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }
    
    if (dest_addr == g_stlocal_devinfo.dest_addr) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, dest_addr);
    send_cmd[5] = sizeof(dest_addr);
    send_cmd[6] = WLT_HTONS(dest_addr) & 0xFF;
    send_cmd[7] = (WLT_HTONS(dest_addr) >> 8) & 0xFF;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set destaddr for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME,"Fail to get destaddr for uart recv fail %d, recv %d \r\n", ret, recved_len);
        return -1;
    }
    
    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", g_uslocal_addr);
            return ret;
        }
        g_stlocal_devinfo.dest_addr = dest_addr;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_get_rf_datarate(uint8_t *pucdatarate)
{
    if (NULL == pucdatarate) {
        LOGE(MODULE_NAME, "Invalid input");
        return -1;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    *pucdatarate = g_stlocal_devinfo.datarate;

    return 0;
}

int32_t wlt3408nz_set_rt_datarate(uint8_t rf_datarate)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    if (rf_datarate > RF_DATARATE_MAX) {
        LOGE(MODULE_NAME, "Invalid input %d", rf_datarate);
        return -1;
    }

    if (rf_datarate == g_stlocal_devinfo.datarate) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, datarate);
    send_cmd[5] = sizeof(rf_datarate);
    send_cmd[6] = rf_datarate;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set rf datarate for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME,"Fail to get rf datarate for uart recv fail %d, recv %d \r\n", ret, recved_len);
        return -1;
    }
    
    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", g_uslocal_addr);
            return ret;
        }
        g_stlocal_devinfo.datarate = rf_datarate;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_get_sendmode(uint8_t *pucsendmode)
{
    if (NULL == pucsendmode) {
        LOGE(MODULE_NAME, "Invalid input");
        return -1;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    *pucsendmode = g_stlocal_devinfo.sendmode;

    return 0;
}

int32_t wlt3408nz_set_sendmode(uint8_t sendmode)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    if (sendmode > SENDMODE_MAX) {
        LOGE(MODULE_NAME, "Invalid input %d", sendmode);
        return -1;
    }

    if (sendmode == g_stlocal_devinfo.sendmode) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, sendmode);
    send_cmd[5] = sizeof(sendmode);
    send_cmd[6] = sendmode;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set sendmode for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME,"Fail to set sendmode for uart recv fail %d, recv %d \r\n", ret, recved_len);
        return -1;
    }
    
    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", g_uslocal_addr);
            return ret;
        }
        g_stlocal_devinfo.sendmode = sendmode;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_get_rf_powerlevel(uint8_t *pucpowerlevel)
{
    if (NULL == pucpowerlevel) {
        LOGE(MODULE_NAME, "Invalid input");
        return -1;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    *pucpowerlevel = g_stlocal_devinfo.powerlevel;

    return 0;
}

int32_t wlt3408nz_set_rf_powerlevel(uint8_t rf_powerlevel)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }
    
    if (rf_powerlevel == g_stlocal_devinfo.powerlevel) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, powerlevel);
    send_cmd[5] = sizeof(rf_powerlevel);
    send_cmd[6] = rf_powerlevel;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set rf powerlevel for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME,"Fail to set powerlevel for uart recv fail %d, recv %d \r\n", ret, recved_len);
        return -1;
    }

    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", g_uslocal_addr);
            return ret;
        }
        g_stlocal_devinfo.powerlevel = rf_powerlevel;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_get_rf_retry_num(uint8_t *pucretrynum)
{
    if (NULL == pucretrynum) {
        LOGE(MODULE_NAME, "Invalid input");
        return -1;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    *pucretrynum = g_stlocal_devinfo.retrynum;

    return 0;
}

int32_t wlt3408nz_set_rf_retry_num(uint8_t rf_retrynum)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }
    
    if (rf_retrynum == g_stlocal_devinfo.retrynum) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, retrynum);
    send_cmd[5] = sizeof(rf_retrynum);
    send_cmd[6] = rf_retrynum;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set rf powerlevel for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME,"Fail to set powerlevel for uart recv fail %d, recv %d \r\n", ret, recved_len);
        return -1;
    }

    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", g_uslocal_addr);
            return ret;
        }
        g_stlocal_devinfo.retrynum = rf_retrynum;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_get_rf_retry_timeout(uint16_t *pusretrytimeout)
{
    if (NULL == pusretrytimeout) {
        LOGE(MODULE_NAME, "Invalid input");
        return -1;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    *pusretrytimeout = g_stlocal_devinfo.retry_timeout;

    return 0;
}

int32_t wlt3408nz_set_rf_retry_timeout(uint16_t rf_retrytimeout)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }
    
    if (rf_retrytimeout == g_stlocal_devinfo.retry_timeout) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, retry_timeout);
    send_cmd[5] = sizeof(rf_retrytimeout);
    send_cmd[6] = WLT_HTONS(rf_retrytimeout) & 0xFF;
    send_cmd[7] = (WLT_HTONS(rf_retrytimeout) >> 8) & 0xFF;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set rf powerlevel for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME,"Fail to set powerlevel for uart recv fail %d, recv %d \r\n", ret, recved_len);
        return -1;
    }
    
    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", g_uslocal_addr);
            return ret;
        }
        g_stlocal_devinfo.retry_timeout = rf_retrytimeout;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_get_rf_channel(uint8_t *pucrfchannel)
{
    if (NULL == pucrfchannel) {
        LOGE(MODULE_NAME, "Invalid input");
        return -1;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    *pucrfchannel = g_stlocal_devinfo.channel;

    return 0;
}

int32_t wlt3408nz_set_rf_channel(uint8_t rf_channel)
{
    int32_t ret = 0;
    uint32_t recved_len = 0;
    uint8_t send_cmd[] = {0xAB, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA};
    st_dev_info_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }
    
    if (rf_channel == g_stlocal_devinfo.channel) {
        return 0;
    }

    if (rf_channel > RF_CHANNEL_26 || rf_channel < RF_CHANNEL_11) {
        LOGE(MODULE_NAME, "Invalid input %d ", rf_channel);
        return -1;
    }
    
    send_cmd[2] = WLT_HTONS(g_uslocal_addr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(g_uslocal_addr) >> 8) & 0xFF;
    send_cmd[4] = aos_offsetof(st_dev_info_t, channel);
    send_cmd[5] = sizeof(rf_channel);
    send_cmd[6] = rf_channel;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set rf powerlevel for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (recved_len != sizeof(st_rsp) || ret != 0) {
        LOGE(MODULE_NAME,"Fail to set powerlevel for uart recv fail %d, recv %d \r\n", ret, recved_len);
        return -1;
    }
    
    if (st_rsp.magic_head == 0xAB && 
        st_rsp.magic_tail == 0xBA &&
        st_rsp.command == 0xD3 && 
        st_rsp.response == 0) {
        ret = wlt3408nz_dev_reset_cmd(g_uslocal_addr);
        if (ret) {
            LOGE(MODULE_NAME, "dev 0x%x reset fail", g_uslocal_addr);
            return ret;
        }
        g_stlocal_devinfo.channel = rf_channel;
        return 0;
    }

    LOGE(MODULE_NAME, "response fail 0x%x", st_rsp.response);
    
    return -1;
}

int32_t wlt3408nz_dev_search(uint8_t expect_num, uint8_t *puc_detectednum, uint16_t *pus_devaddr)
{
    int32_t ret = 0;
    uint8_t i = 0;
    uint8_t send_cmd[] = {0xAB, 0xD5, 0xBA};
    uint32_t recved_len = 0;
    uint8_t  detectnum = 0;
    st_dev_search_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    if (NULL == puc_detectednum || 0 == expect_num || NULL == pus_devaddr) {
        LOGE(MODULE_NAME, "Invalid input %d ", expect_num);
        return -1;
    }
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set rf powerlevel for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    for(i = 0; i < expect_num; i++) {
        memset(&st_rsp, 0, sizeof(st_rsp));
        ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                            &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
        if (ret || recved_len != sizeof(st_rsp)) {
            continue;
        }

        if (st_rsp.magic_head == 0xAB && st_rsp.magic_tail == 0xBA
            && st_rsp.command == 0xD5) {
            pus_devaddr[detectnum] = WLT_NTOHS(st_rsp.addr);
            detectnum++;
        }
    }
    
    *puc_detectednum = detectnum;
    
    aos_mutex_unlock(&st_zigbee_uart_mutex);

    return 0;
}

int32_t wlt3408nz_dev_online_check(uint16_t usdevaddr)
{
    int32_t ret = 0;
    uint8_t send_cmd[] = {0xAB, 0xD6, 0x00, 0x00, 0xBA};
    uint32_t recved_len = 0;
    st_dev_search_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    if (usdevaddr == g_uslocal_addr) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(usdevaddr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(usdevaddr) >> 8) & 0xFF;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set rf powerlevel for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    memset(&st_rsp, 0, sizeof(st_rsp));
    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                        &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);

    if (st_rsp.magic_head == 0xAB && st_rsp.magic_tail == 0xBA
        && st_rsp.command == 0xD6 && WLT_NTOHS(st_rsp.addr) == usdevaddr) {
        return 0;
    }
    
    return -1;
}

static int32_t wlt3408nz_dev_factory_reset(uint16_t usdevaddr)
{
    int32_t ret = 0;
    uint8_t send_cmd[] = {0xAB, 0xDB, 0x00, 0x00, 0x10, 0x00, 0xBA};
    uint32_t recved_len = 0;
    st_dev_search_rsp_t st_rsp = {0};

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    if (usdevaddr == g_uslocal_addr) {
        return 0;
    }

    send_cmd[2] = WLT_HTONS(usdevaddr) & 0xFF;
    send_cmd[3] = (WLT_HTONS(usdevaddr) >> 8) & 0xFF;
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, send_cmd, sizeof(send_cmd), 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to set rf powerlevel for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    memset(&st_rsp, 0, sizeof(st_rsp));
    ret = hal_uart_recv_II(&st_zigbee_uart, &st_rsp, sizeof(st_rsp), 
                        &recved_len, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);

    if (st_rsp.magic_head == 0xAB && st_rsp.magic_tail == 0xBA
        && st_rsp.command == 0xDB && st_rsp.status == 0) {
        return 0;
    }
    
    return -1;
}

static int32_t wlt3408nz_dev_host_data_send(uint16_t destaddr, uint8_t *pdata, uint8_t length)
{
    int32_t ret = 0;
    uint8_t aucsendcmd[PACKET_MAX_PAYLOAD_LENGTH + 5] = {0};
    uint32_t sendlength = 0;
    st_host_data_rsp_t st_dataresp = {0};
    
    if (NULL == pdata || length > PACKET_MAX_PAYLOAD_LENGTH) {
        LOGE(MODULE_NAME, "Invalid input %d ", length);
        return -1;
    }

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    sendlength = length + 5;
    memset(aucsendcmd, 0, PACKET_MAX_PAYLOAD_LENGTH + 5);
    aucsendcmd[0] = 0xAA;
    aucsendcmd[1] = 0xD1;
    aucsendcmd[2] = WLT_HTONS(destaddr) & 0xFF;
    aucsendcmd[3] = (WLT_HTONS(destaddr) >> 8) & 0xFF;
    memcpy(aucsendcmd + 4, pdata, length);
    aucsendcmd[sendlength - 1] = 0x55;

    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, aucsendcmd, sendlength, 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to send data for uart send fail %d", ret);
        aos_mutex_unlock(&st_zigbee_uart_mutex);
        return -1;
    }

    memset(&st_dataresp, 0, sizeof(st_dataresp));
    ret = hal_uart_recv_II(&st_zigbee_uart, &st_dataresp, sizeof(st_dataresp), 
                        &sendlength, ZIGBEE_UART_DEFAULT_TIMEOUT);
    aos_mutex_unlock(&st_zigbee_uart_mutex);

    if (st_dataresp.magic_head == 0xAA && st_dataresp.magic_tail == 0x55
        && st_dataresp.command == 0xD0 && st_dataresp.status == 0) {
        return 0;
    }
    
    return -1;
}

static int32_t wlt3408nz_dev_terminal_data_send(uint16_t destaddr, uint8_t *pdata, uint8_t length)
{
    int32_t ret = 0;
    uint16_t curr_dest_addr = 0;

    if (NULL == pdata || length > PACKET_MAX_PAYLOAD_LENGTH) {
        LOGE(MODULE_NAME, "Invalid input %d ", length);
        return -1;
    }

    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return -1;
    }

    wlt3408nz_get_dest_addr(&curr_dest_addr);
    if (curr_dest_addr != destaddr) {
        /*we need to set dest addr at first*/
        ret = wlt3408nz_set_dest_addr(destaddr);
        if (ret) {
            LOGE(MODULE_NAME, "Fail to set dest addr %d", destaddr);
            return -1;
        }
    }
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);

    ret = hal_uart_send(&st_zigbee_uart, pdata, length, 
                        ZIGBEE_UART_DEFAULT_TIMEOUT);
    
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (ret) {
        LOGE(MODULE_NAME,"Fail to send data for uart send fail %d", ret);
        return -1;
    }
    
    return 0;
}


int32_t wlt3408nz_dev_data_send(uint16_t destaddr, uint8_t *pdata, uint8_t length)
{
    int32_t ret = -1;
    uint8_t workmode = 0;

    if (NULL == pdata || length > PACKET_MAX_PAYLOAD_LENGTH) {
        LOGE(MODULE_NAME, "Invalid input %d ", length);
        return ret;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return ret;
    }
    
    ret = wlt3408nz_get_dev_work_mode(&workmode);
    if(ret) {
        LOGE(MODULE_NAME,"Fail to get device workmode");
        return ret;
    }
    
    if (workmode == WORKMODE_HOST || workmode == WORKMODE_HOST_RELAY) {
        ret = wlt3408nz_dev_host_data_send(destaddr, pdata, length);
    }
    
    if (workmode == WORKMODE_TERMINAL || workmode == WORKMODE_TERMINAL_RELAY) {
        ret = wlt3408nz_dev_terminal_data_send(destaddr, pdata, length);
    } 

    return ret;
}

static int32_t wlt3408nz_dev_host_data_recv(uint16_t *pussrcaddr, uint8_t *pdata, uint8_t length)
{
    int32_t ret = -1;
    uint8_t aucrecvdata[PACKET_MAX_PAYLOAD_LENGTH + 5] = {0};
    uint32_t expect_size = 0;
    uint32_t recved_size = 0;
    
    if (NULL == pdata || NULL == pussrcaddr
        || length > PACKET_MAX_PAYLOAD_LENGTH) {
        LOGE(MODULE_NAME, "Invalid input %d ", length);
        return ret;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return ret;
    }
    
    memset(aucrecvdata, 0, sizeof(aucrecvdata));

    expect_size = length + 5;

    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);
    
    ret = hal_uart_recv_II(&st_zigbee_uart, aucrecvdata, expect_size, 
                        &recved_size, ZIGBEE_UART_DEFAULT_TIMEOUT);
    
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    
    if (recved_size == expect_size && aucrecvdata[0] == 0xAA &&
        aucrecvdata[1] == 0xD1 && aucrecvdata[expect_size - 1] == 0x55) {
        *pussrcaddr = WLT_NTOHS(*(uint16_t *)&aucrecvdata[2]);
        memcpy(pdata, aucrecvdata + 4, length);
        return 0;
    }

    //LOGE(MODULE_NAME, "Fail to data ret %d recved size %d", ret, recved_size);
    return -1;
}

static int32_t wlt3408nz_dev_terminal_data_recv(uint16_t *pussrcaddr, uint8_t *pdata, uint8_t length)
{
    int32_t ret = -1;
    uint32_t recved_size = 0;
    
    if (NULL == pdata || NULL == pussrcaddr
        || length > PACKET_MAX_PAYLOAD_LENGTH) {
        LOGE(MODULE_NAME, "Invalid input %d ", length);
        return ret;
    }

    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return ret;
    }
    
    aos_mutex_lock(&st_zigbee_uart_mutex, AOS_WAIT_FOREVER);
    
    ret = hal_uart_recv_II(&st_zigbee_uart, pdata, length, 
                        &recved_size, ZIGBEE_UART_DEFAULT_TIMEOUT);
    
    aos_mutex_unlock(&st_zigbee_uart_mutex);
    if (recved_size == length && ret == 0) {
        return 0;
    }
    if(recved_size != length)
    {
        return -8;
    }
    //LOGE(MODULE_NAME, "Fail to data ret %d recved size %d", ret, recved_size);
    return -1;
}

int32_t wlt3408nz_dev_data_recv(uint16_t *pussrcaddr, uint8_t *pdata, uint8_t length)
{
    int32_t ret = -1;
    uint8_t workmode = 0;

    if (NULL == pdata || NULL == pussrcaddr
        || length > PACKET_MAX_PAYLOAD_LENGTH) {
        LOGE(MODULE_NAME, "Invalid input %d ", length);
        return ret;
    }
    
    if (zigbee_init_flag != 1) {
        LOGE(MODULE_NAME,"zigbee dev haven't init yet \r\n");
        return ret;
    }
    
    ret = wlt3408nz_get_dev_work_mode(&workmode);
    if(ret) {
        LOGE(MODULE_NAME,"Fail to get device workmode");
        return ret;
    }
    if (workmode == WORKMODE_HOST || workmode == WORKMODE_HOST_RELAY) {
        ret = wlt3408nz_dev_host_data_recv(pussrcaddr, pdata, length);
    }
    
    if (workmode == WORKMODE_TERMINAL || workmode == WORKMODE_TERMINAL_RELAY) {
        ret = wlt3408nz_dev_terminal_data_recv(pussrcaddr, pdata, length);
    } 

    return ret;
}



